'''
Created on May 21, 2011

@author: Igor
'''

from lib.common_cards import NUMBER_OF_CARDS, get_combos_with_indicators,\
    cmp_hand

from challenge_helper import add_bid, betting_round_finished, Decision, \
        call_bet

from decimal import Decimal, getcontext
        
class PlayerType:
    SUPER_FISH=0
    FISH=1
    ROCK=2
    MANIAC=3
    BOMB=4
    SHARK=5

# Confidence required to make a call
_CALL_CONFIDENCE_LEVEL = [["0", "0", "0", "0", "0", "0", "0"],
        ["0", "0.25", "0.5", "0.75", "0.875", "0.9375", "0.96875"]]

def get_probs(my_cards, table_cards):
    getcontext().prec = 5
    # Setup the new deck
    deck = range(NUMBER_OF_CARDS)
    # Remove the ones we have seen:
    for card in my_cards:
        deck.remove(card)
    for card in table_cards:
        deck.remove(card)
    wins = 0
    ties = 0
    losses = 0
    my_combos = get_combos_with_indicators(my_cards + table_cards)
    # Try all possibilities of the opponent's hand
    for first_card in xrange(len(deck)-1):
        for i in xrange(len(deck)-first_card-1):
            second_card = i + first_card + 1
            your_cards = [deck[first_card], deck[second_card]]
            result = cmp_hand(my_combos, your_cards + table_cards)
            if result > 0:
                wins += 1
            elif result == 0:
                ties += 1
            else:
                losses += 1
    wins = Decimal(wins)
    ties = Decimal(ties)
    losses = Decimal(losses)
    total = wins + ties + losses
    win_prob = wins / total
    tie_prob = ties / total
    loss_prob = losses / total
    ret_list = [win_prob, tie_prob, loss_prob]
    return ret_list

def make_decision(game, call_amount, prev_amount):
    counter_amount = prev_amount / 2
    counter = 0
    while call_amount > counter_amount and counter < 6:
        counter_amount *= 2
        counter += 1
    confidence_str = _CALL_CONFIDENCE_LEVEL[game.challenge_level][counter]
    confidence = Decimal(confidence_str)
    my_cards = [int(i) for i in game.my_cards]
    table_cards = []
    if game.round > 1:
        table_cards = [int(i) for i in game.table_cards]
        table_cards = table_cards[:game.round+1]
    probs_list = get_probs(my_cards, table_cards)
    if confidence <= probs_list[0] + probs_list[1]:
        game.debug = "Since the probs are " + str(probs_list) + \
        " and confidence required is %s, I CALLED %d. " % (confidence_str,
                                                           call_amount)
        game.message += "I decided to CALL %d. " % call_amount
        return 1
    else:
        game.debug = "My cards were " + str(my_cards) + \
        ". Since the probs are " + str(probs_list) + \
        " and confidence required is %s, I FOLDED to %d. " % (confidence_str,
                                                              call_amount)
        return 0

def make_move(game):
    if game.all_in:
        print "We are all-in, i shouldn't be making moves!"
        raise
    if game.balance < 0:
        print "Something is wrong, the balance shouldn't be negative"
        raise
    # If we can check, CHECK
    if game.balance == 0:
        add_bid(game, 0)
        game.round_over = betting_round_finished(game)
        game.message += "After some thinking I decided to CHECK. "
        return Decision.CHECK
    call_amount = min(game.my_money, game.balance)
    prev_amount = game.pot_money - game.balance
    decision = make_decision(game, call_amount, prev_amount)
    if decision == 0:
        return Decision.FOLD
    elif decision == 1:
        return call_bet(game)
    else:
        print "Not implemented yet"
        raise